home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Messaging / NamRslvr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  61.1 KB  |  2,098 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        NamRslvr.cpp
  3.  
  4.     Contains:    Implementation of Mac version of ODNameResolver class
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <9>      12/19/96    JP        1614769: Make TokenDefaultCanHandle return
  13.                                     true
  14.          <8>      12/13/96    JP        1607652: Added & disabled debugging code
  15.          <7>     9/23/96    JP        1384958: Renamed GetDefaultRootFrame
  16.          <6>     6/20/96    JP        1323103: Removed an ASSERT & added optional
  17.                                     logging
  18.          <5>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  19.          <4>    .04.1996    NP        Change ObjectMaster #define for parsing.
  20.          <3>     3/14/96    NP        1290949, 1291292: Fix memory leaks with
  21.                                     whose and every clauses.
  22.          <2>     1/15/96    TJ        Cleaned Up
  23.  
  24.     To Do:
  25.     In Progress:
  26.         
  27. */
  28.  
  29. #ifndef SOM_ODPart_xh
  30. #include "Part.xh"
  31. #endif
  32.  
  33. #ifndef _ODDESUTL_
  34. #include <ODDesUtl.h>
  35. #endif
  36.  
  37. #ifndef _DFLTACS_
  38. #include <DfltAcs.h>
  39. #endif
  40.  
  41. #ifndef SOM_ODDesc_xh
  42. #include "ODDesc.xh"
  43. #endif
  44.  
  45. #ifndef SOM_ODOSLToken_xh
  46. #include "ODOSLTkn.xh"
  47. #endif
  48.  
  49. #ifndef SOM_ODObjectSpec_xh
  50. #include "ODObjSpc.xh"
  51. #endif
  52.  
  53. #ifndef _SEPRIV_
  54. #include "SEPriv.h"
  55. #endif
  56.  
  57. #ifndef _SEUTILS_
  58. #include "SEUtils.h"
  59. #endif
  60.  
  61. #ifndef SOM_ODMessageInterface_xh
  62. #include "MssgIntf.xh"
  63. #endif
  64.  
  65. #ifndef SOM_DefaultAccessorSI_xh
  66. #include "MssgSI.xh"
  67. #endif
  68.  
  69. #ifndef SOM_ODSession_xh
  70. #include "ODSessn.xh"
  71. #endif
  72.  
  73. #ifndef SOM_ODFrame_xh
  74. #include "Frame.xh"
  75. #endif
  76.  
  77. #ifndef SOM_ODPartWrapper_xh
  78. #include "PartWrap.xh"
  79. #endif
  80.  
  81. #ifndef SOM_ODSemanticInterface_xh
  82. #include "SemtIntB.xh"
  83. #endif
  84.  
  85. #ifndef _TEMPSI_
  86. #include "TempSI.h"
  87. #endif
  88.  
  89. #ifndef _OSLTOKEN_
  90. #include "OSLToken.h"
  91. #endif
  92.  
  93. #ifndef _CNTXTOSL_
  94. #include "CntxtOSL.h"
  95. #endif
  96.  
  97. #ifndef _EXCEPT_
  98. #include "Except.h"
  99. #endif
  100.  
  101. #ifndef _OPENHASH_
  102. #include "OpenHash.h"
  103. #endif
  104.  
  105. #ifndef _PLFMDEF_
  106. #include "PlfmDef.h"
  107. #endif
  108.  
  109. #ifndef _SIHLPABS_
  110. #include "SIHlpAbs.h"
  111. #endif
  112.  
  113. #ifndef _ODREGISTRY_
  114. #include "ODRgstry.xh"
  115. #endif
  116.  
  117. #ifndef _DFLTACS_
  118. #include "DfltAcs.h"
  119. #endif
  120.  
  121. #define VARIABLE_MACROS
  122. #define ODNameResolver_Class_Source
  123. #include <NamRslvr.xih>
  124.  
  125. #ifndef SOM_ODExtension_xh
  126. #include <Extensn.xh>
  127. #endif
  128.  
  129. #ifndef _ODDEBUG_
  130. #include "ODDebug.h"
  131. #endif
  132.  
  133. #ifndef _ODMEMORY_
  134. #include "ODMemory.h"
  135. #endif
  136.  
  137. #ifndef _ORDCOLL_
  138. #include "OrdColl.h"
  139. #endif
  140.  
  141. #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
  142. #include "StdExts.xh"
  143. #endif
  144.  
  145. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  146. #include <StdDefs.xh>
  147. #endif
  148.  
  149. #pragma segment ODNameResolver
  150.  
  151. #include "NamRslvB.cpp"    // Platform-independent methods, if any
  152.  
  153. //#undef LOGGING
  154. //#define LOGGING 1
  155.  
  156. //==============================================================================
  157. // Some implementation pointers.
  158. //==============================================================================
  159. /*
  160.  
  161. Format of an ODOSLToken:
  162.  
  163. -descriptorType: typeUserToken
  164.  
  165. -dataHandle is 12 bytes long. The first 4 bytes contain an ODDesc* and
  166. the second 8 bytes contain an embedded OSLContext.
  167.  
  168. */
  169. //==============================================================================
  170. // Constants
  171. //==============================================================================
  172.  
  173. const ODULong kNumPartsExpected = 20; // number of parts expected to be
  174.                                         //    involved in object spec resolution.
  175.  
  176. //==============================================================================
  177. // Function prototypes
  178. //==============================================================================
  179. #define SKIPOMPARSE
  180. #ifdef SKIPOMPARSE
  181. extern "C" { // functions may be called from a .c file
  182. #endif
  183. CallbackCallerProc ReturnCallbackFuncCaller(OSLCallbackSelector whichCallback);
  184.  
  185. ODStatic OSErr CallObjectAccessor(DescType        desiredClass,
  186.                                 const OSLToken*    containerToken,
  187.                                 DescType        containerClass,
  188.                                 DescType        keyForm,
  189.                                 const AEDesc*    keyData,
  190.                                 OSLToken*        value,
  191.                                 Boolean*        procFound,
  192.                                 long            contextRefCon);
  193.                                 
  194. ODStatic OSErr CallCountProc(DescType            desiredClass,
  195.                                 DescType        containerClass,
  196.                                 const OSLToken*    container,
  197.                                 long*            result,
  198.                                 long            contextRefCon);
  199.                                 
  200. ODStatic OSErr CallCompareProc(DescType            oper,
  201.                                 const AEDesc*    obj1,
  202.                                 const AEDesc*    obj2,
  203.                                 ODBoolean*        result,
  204.                                 long            contextRefCon);
  205.                                 
  206. ODStatic OSErr CallDisposeTokenProc(OSLToken*    unneededToken,
  207.                                     long        contextRefCon);
  208.  
  209. ODStatic OSErr CallMarkProc(const OSLToken*    dToken,
  210.                             const OSLToken*    markToken,
  211.                             long            index,
  212.                             long            contextRefCon);
  213.  
  214. ODStatic OSErr CallGetMarkTokenProc(const OSLToken*    dContainerToken,
  215.                                     DescType        containerClass,
  216.                                     OSLToken*        result,
  217.                                     long            contextRefCon);
  218.  
  219. ODStatic OSErr CallAdjustMarksProc(long                newStart,
  220.                                     long            newStop,
  221.                                     const OSLToken*    markToken,
  222.                                     long            contextRefCon);
  223.  
  224. ODStatic OSErr CallGetErrDescProc(AEDesc**    appDescPtr,
  225.                                     long    contextRefCon);
  226.  
  227. ODStatic long GetAppDoesFlags(long contextRefCon);
  228. #ifdef SKIPOMPARSE
  229. }
  230. #endif
  231.  
  232. ODPart* PartFromContext(OSLContext* context);
  233. ODFrame* FrameFromContext(OSLContext* context);
  234. static ODBoolean TokenDefaultCanHandle( Environment* ev,
  235.         ODNameResolver* resolver, ODOSLToken* token );
  236. ODDesc* GetUserODToken(OSLToken* oslToken);
  237. void SetUserODToken(OSLToken* oslToken, ODDesc* odDesc);
  238. static void NewODToken( ODNameResolver* me, ODOSLToken* openDocToken,
  239.                          ODPart* part, ODFrame* frame, OSLToken* newToken);
  240.  
  241. //==============================================================================
  242. // SIContext
  243. //==============================================================================
  244.  
  245. class SIContext
  246. {
  247.   public:
  248.  
  249.     SIContext(Environment* ev, ODPart* part, ODFrame* frame,
  250.                 ODNameResolver* resolver,
  251.                 ODBoolean isDefaultToken = kODFalse);
  252.     ~SIContext();
  253.     
  254.     ODPart*             GetPart() {return fPart;}
  255.     ODFrame*             GetFrame() {return fFrame;}
  256.     ODNameResolver*        GetNameResolver() {return fNameResolver;}
  257.     ODBoolean             IsDefaultToken() {return fIsDefaultToken;}
  258.     void                 SetIsDefaultToken(ODBoolean isDefault)
  259.                                             {fIsDefaultToken = isDefault;}
  260.   private:
  261.     ODPart*            fPart;
  262.     ODFrame*        fFrame;
  263.     ODNameResolver*    fNameResolver;
  264.     ODBoolean        fIsDefaultToken;
  265. };
  266.  
  267. SIContext::SIContext(Environment* ev, ODPart* part, ODFrame* frame ,
  268.                 ODNameResolver* resolver,
  269.                 ODBoolean isDefaultToken)
  270. {
  271.     if (part)
  272.         part->Acquire(ev);
  273.     if (frame)
  274.         frame->Acquire(ev);
  275.     fPart = part;
  276.     fFrame = frame;
  277.     fNameResolver = resolver;
  278.     fIsDefaultToken = isDefaultToken;
  279.     
  280.     LOG(" SIContext %8.8x created part=%8.8x, frame=%8.8x\n", this, fPart, fFrame);
  281.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  282. }
  283.  
  284. SIContext::~SIContext()
  285. {
  286.     Environment*    ev = somGetGlobalEnvironment();
  287.  
  288.     LOG("SIContext %8.8x released part=%8.8x, frame=%8.8x\n", this, fPart, fFrame);
  289.     TRY
  290.         if (fPart)
  291.             fPart->Release(ev);
  292.         if (fFrame)
  293.             fFrame->Release(ev);
  294.     CATCH_ALL
  295.     ENDTRY
  296. }
  297.  
  298. //------------------------------------------------------------------------------
  299. // DeleteAContext
  300. //------------------------------------------------------------------------------
  301.  
  302. inline void DeleteAContext(OSLContext* context)
  303. {
  304.     LOG("SIContext %8.8x destroyed\n", context->refCon);
  305.     delete (SIContext*)(context->refCon);
  306. #if ODDebug
  307.     context->refCon = 0x50FF8001;
  308. #endif
  309. //    delete context;
  310. }
  311.  
  312. //------------------------------------------------------------------------------
  313. // PartFromContext
  314. //------------------------------------------------------------------------------
  315.  
  316. ODPart* PartFromContext(OSLContext* context)
  317. {
  318.     ODPart*    part = ((SIContext*)(context->refCon))->GetPart();
  319.     LOG("Part %8.8x returned from SIContext %8.8x\n", part, context->refCon);
  320.     return part;
  321. }
  322.  
  323. //------------------------------------------------------------------------------
  324. // FrameFromContext
  325. //------------------------------------------------------------------------------
  326.  
  327. ODFrame* FrameFromContext(OSLContext* context)
  328. {
  329.     ODFrame* frame = ((SIContext*)(context->refCon))->GetFrame();
  330.     LOG("Frame %8.8x returned from SIContext %8.8x\n", frame, context->refCon);
  331.     return frame;
  332. }
  333.  
  334. //------------------------------------------------------------------------------
  335. // SIContextFromOSLToken
  336. //
  337. //    Return pointer to SIContext that is referenced from this OSLToken.
  338. //------------------------------------------------------------------------------
  339.  
  340. static SIContext* SIContextFromOSLToken(ODNameResolver* resolver,
  341.                                         const OSLToken* token)
  342. {
  343.     WASSERT(token->dataHandle != kODNULL);
  344.     OSLContext context;
  345.     OSLGetTokenContext(token, &context);
  346.     return (SIContext*)(context.refCon);
  347. }
  348.  
  349. //------------------------------------------------------------------------------
  350. // SIContextFromToken
  351. //
  352. //    Return pointer to SIContext that is referenced from this ODOSLToken.
  353. //------------------------------------------------------------------------------
  354.  
  355. static SIContext* SIContextFromToken(ODNameResolver* resolver,
  356.                                         ODOSLToken* token)
  357. {
  358.     AEDesc    tokenAsAEDesc;
  359.     SIContext*    retVal;
  360.  
  361.     WASSERT(token != kODNULL);
  362.     THROW_IF_ERROR(ODDescToAEDesc(token, &tokenAsAEDesc));
  363.     WASSERT(tokenAsAEDesc.dataHandle != kODNULL);
  364.     retVal = SIContextFromOSLToken(resolver, &tokenAsAEDesc);
  365.     AEDisposeDesc(&tokenAsAEDesc);
  366.     return retVal;
  367. }
  368.  
  369. //------------------------------------------------------------------------------
  370. // SetIsDefaultToken
  371. //------------------------------------------------------------------------------
  372.  
  373. static void SetIsDefaultToken(ODNameResolver* resolver,
  374.                                 ODOSLToken* token, ODBoolean isDefaultToken)
  375. {
  376.     WASSERT(token != kODNULL);
  377.     SIContext* sic = SIContextFromToken(resolver, token);
  378.     WASSERT(sic != kODNULL);
  379.     sic->SetIsDefaultToken(isDefaultToken);
  380. }
  381.  
  382. //------------------------------------------------------------------------------
  383. // MakeNULLToken
  384. //------------------------------------------------------------------------------
  385.  
  386. inline static void MakeNULLToken( OSLToken *theToken )
  387. {
  388.     theToken->descriptorType = typeNull ;
  389.     theToken->dataHandle = NULL ;
  390. }
  391.     
  392. //==============================================================================
  393. // SIContextTableKey
  394. //==============================================================================
  395.  
  396. struct SIContextTableKey
  397. {
  398.     ODPart*        fPart;
  399.     ODFrame*    fFrame;
  400.     SIContextTableKey(ODPart* part, ODFrame* frame) {fPart = part;
  401.                                                         fFrame = frame;}
  402. };
  403.  
  404. //==============================================================================
  405. // ODNameResolver
  406. //==============================================================================
  407.  
  408. //------------------------------------------------------------------------------
  409. // ODNameResolver::somInit
  410. //------------------------------------------------------------------------------
  411.  
  412. //------------------------------------------------------------------------------
  413. // ODNameResolver::InitNameResolver
  414. //------------------------------------------------------------------------------
  415.  
  416. SOM_Scope void  SOMLINK ODNameResolverInitNameResolver(ODNameResolver *somSelf, Environment *ev,
  417.         ODSession* session)
  418. {
  419.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  420.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverInitNameResolver");
  421.  
  422.     SOM_TRY
  423.  
  424.     /* Moved from somInit. SOM itself sets fields to zero
  425.     _fRootContext.getCallerProc = kODNULL;
  426.     _fRootContext.refCon = 0;
  427.     _fCurrentlyResolving = 0;
  428.     _fSession = kODNULL;
  429.     _fContextTable = kODNULL;
  430.     _fCurrentContextPart = kODNULL;
  431.     _fHashTableRefCount = 0;
  432.     */
  433.     
  434.     somSelf->InitObject(ev);
  435.  
  436.     _fSession = session;
  437.  
  438.     const ODUShort        kODOSLContextSize = sizeof(OSLContext);
  439.     const ODBoolean        kNotInSystemHeap = kODFalse;
  440.     ODFrame* const        kNoFrameInfo = kODNULL;
  441.  
  442.     somSelf->CreateContext(ev, kODAppShell, kNoFrameInfo, &_fRootContext);
  443.     THROW_IF_ERROR(OSLObjectInit(&_fRootContext));
  444.     THROW_IF_NULL(_fContextTable = new OpenHashTable(OpenHashTable::EqualTwoLongs, OpenHashTable::HashTwoLongs) );
  445.     _fContextTable->Initialize(kNumPartsExpected, sizeof(SIContextTableKey),
  446.                                 kODOSLContextSize);
  447.     _fCurrentContextPart = new OrderedCollection;
  448.     somSelf->AddNewContextPartToTopOfStack(ev, (ODPart*)kODAppShell);
  449. //    _fCurrentContextPart = kODAppShell;
  450.     _fErrDescList = new OrderedCollection;
  451.  
  452.     SOM_CATCH_ALL
  453.     SOM_ENDTRY
  454. }
  455.  
  456. //------------------------------------------------------------------------------
  457. // ODNameResolver::somUninit
  458. //------------------------------------------------------------------------------
  459.  
  460. SOM_Scope void  SOMLINK ODNameResolversomUninit(ODNameResolver *somSelf)
  461. {
  462.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  463.     ODNameResolverMethodDebug("ODNameResolver","somUninit");
  464.  
  465.     TRY
  466.         // somSelf->FlushContextCache(somGetGlobalEnvironment());
  467.         // It is incorrect to call methods on somSelf inside somUninit, 
  468.         // a subclass may have already been somUninited.  See OpenDoc Building Code for details.
  469.         // Instead the implementation of FlushContextCache has been copied here.
  470.         
  471.         if (_fContextTable)
  472.         {
  473.             // BEGIN copy of FlushContextCache implementation
  474.             OSLContext                value;
  475.             OpenHashTableIterator   i(_fContextTable);
  476.             
  477.             if (_fHashTableRefCount == 0)
  478.                 for (i.First((void*) 0, &value); i.IsNotComplete(); i.Next((void*) 0, &value))
  479.                 {
  480.                     DeleteAContext(&value);
  481.                     i.RemoveCurrent();
  482.                 }
  483.             // END copy of FlushContextCache implementation
  484.         }
  485.         
  486.     CATCH_ALL
  487.     ENDTRY
  488.         
  489.     DeleteAContext(&_fRootContext);
  490.     ODDeleteObject(_fContextTable);
  491.     ODDeleteObject(_fCurrentContextPart);
  492.     ODDeleteObject(_fErrDescList);
  493. }
  494. #if 0
  495. //------------------------------------------------------------------------------
  496. // ODNameResolver::Purge
  497. //------------------------------------------------------------------------------
  498.  
  499. SOM_Scope ODSize  SOMLINK ODNameResolverPurge(ODNameResolver *somSelf, Environment *ev,
  500.         ODSize size)
  501. {
  502. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  503.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverPurge");
  504.  
  505.     ODUnused(size);
  506.     return 0;
  507. }
  508. #endif /* 0 */
  509. //------------------------------------------------------------------------------
  510. // ODNameResolver::AddErrDescToList
  511. //------------------------------------------------------------------------------
  512.  
  513. struct ErrorDescRec
  514. {
  515.     AEDesc    aeDesc;
  516.     ODDesc*    odDesc;
  517. };
  518.  
  519. SOM_Scope AEDesc*  SOMLINK ODNameResolverAddErrDescToList(ODNameResolver *somSelf, Environment *ev,
  520.         ODDesc* odDesc)
  521. {
  522.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  523.     ODNameResolverMethodDebug("ODNameResolver","AddErrDescToList");
  524.  
  525.     ErrorDescRec*    descRec = new ErrorDescRec;
  526.     descRec->odDesc = odDesc;
  527.     THROW_IF_ERROR(ODDescToAEDesc(odDesc, &descRec->aeDesc));
  528.     _fErrDescList->AddFirst(descRec);
  529.     return &descRec->aeDesc;
  530. }
  531.  
  532. //------------------------------------------------------------------------------
  533. // ODNameResolver::Resolve
  534. //------------------------------------------------------------------------------
  535.  
  536. // FOR CallGetErrDescProc. WE REALLY SHOULD BE KEEPING A LIST OF THESE FOR EVERY
  537. //    PART. OSL WILL WRITE INTO THE DESCRIPTOR IF IT IS A NULL DESCRIPTOR.
  538. //    IF AN APP RETURNS A NON-NULL DESCRIPTOR, THEN THE OSL WILL NOT WRITE INTO
  539. //    IT (ASSUMING THAT IT WAS A PREVIOUSLY WRITTEN-INTO ONE?
  540.  
  541. SOM_Scope void  SOMLINK ODNameResolverResolve(ODNameResolver *somSelf, Environment *ev,
  542.         ODObjectSpec* theObject, ODOSLToken* token, ODPart* contextPart)
  543. {
  544.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  545.     ODNameResolverMethodDebug("ODNameResolver","Resolve");
  546.  
  547.     OSLContext        context;
  548.     OSErr            error;
  549.     ODFrame* const    kNoFrameInfo = kODNULL;
  550.     ODBoolean        contextPartStackChanged = kODFalse;
  551.  
  552.     SOM_TRY
  553.         somSelf->AddNewContextPartToTopOfStack(ev, contextPart);
  554.         contextPartStackChanged = kODTrue;
  555.  
  556.         ODSemanticInterface* theSI = somSelf->AcquireSemtIntf(ev, contextPart);
  557.         if (!theSI)
  558.             THROW(errAENoSuchObject);
  559.         else if (contextPart != kODAppShell)
  560.             theSI->Release(ev);
  561.  
  562.         somSelf->GetContextForPart(ev, contextPart, kNoFrameInfo, &context);
  563.     
  564.         AEDesc objectSpecifier;
  565.         THROW_IF_ERROR( ODDescToAEDesc( theObject, &objectSpecifier ) );
  566.     
  567. #ifdef TESTING_EXMN
  568.         // replace the null desc at the root of containment with 'exmn'
  569.         (void)Munger( objectSpecifier.dataHandle, 0, "null", 4, "exmn", 4 );
  570. #endif
  571.  
  572.         AEDesc realToken = NULL_DESCRIPTOR_DEFINITION;
  573.     
  574.         ++_fCurrentlyResolving;
  575.         error = OSLResolve(&objectSpecifier, &realToken, &context);
  576.         --_fCurrentlyResolving;
  577.     
  578.         AEDisposeDesc(&objectSpecifier);
  579.         if (error == noErr)
  580.             error = AEDescToODDesc( &realToken, token );
  581.         AEDisposeDesc(&realToken);
  582.         
  583.         somSelf->DeleteTopOfContextPartStack(ev);
  584.  
  585.         THROW_IF_ERROR (error);
  586.     SOM_CATCH_ALL
  587.         if (contextPartStackChanged)
  588.             somSelf->DeleteTopOfContextPartStack(ev);
  589.     SOM_ENDTRY
  590.  
  591.     TRY
  592.         OrderedCollectionIterator    iter(_fErrDescList);
  593.         ErrorDescRec*                element;
  594.     
  595.         for (element = (ErrorDescRec*)iter.First();
  596.                 iter.IsNotComplete();
  597.                 element = (ErrorDescRec*)iter.Next())
  598.         {
  599.             AEDescToODDesc(&element->aeDesc, element->odDesc);
  600.             AEDisposeDesc(&element->aeDesc);
  601.         }
  602.         _fErrDescList->DeleteAll();
  603.     CATCH_ALL
  604.         _fErrDescList->DeleteAll();
  605.     ENDTRY
  606. }
  607.  
  608. //------------------------------------------------------------------------------
  609. // ODNameResolver::AcquireSemtIntf
  610. //
  611. //    Convenience function. Returns the SemanticInterface object associated with
  612. //    an ODPart object or kODNULL if none exists.
  613. //------------------------------------------------------------------------------
  614.  
  615. SOM_Scope ODSemanticInterface*  SOMLINK ODNameResolverAcquireSemtIntf(ODNameResolver *somSelf, Environment *ev,
  616.         ODPart* part)
  617. {
  618.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  619.     ODNameResolverMethodDebug("ODNameResolver","AcquireSemtIntf");
  620.  
  621.     ODSemanticInterface*    theSI;
  622.  
  623.     if (part == kODAppShell)
  624.         theSI = _fSession->AcquireShellSemtInterface(ev);
  625.     else
  626.     {
  627.         if (part->HasExtension(ev, kODExtSemanticInterface))
  628.             theSI = (ODSemanticInterface*)part->AcquireExtension(ev, 
  629.                                                         kODExtSemanticInterface);
  630.         else
  631.             theSI = kODNULL;
  632.     }
  633.  
  634.     return theSI;
  635. }
  636.  
  637. //------------------------------------------------------------------------------
  638. // ODNameResolver::GetSession
  639. //
  640. //    Convenience function. Returns the SemanticInterface object associated with
  641. //    an ODPart object or kODNULL if none exists.
  642. //------------------------------------------------------------------------------
  643.  
  644. SOM_Scope ODSession*  SOMLINK ODNameResolverGetSession(ODNameResolver *somSelf, Environment *ev)
  645. {
  646.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  647.     ODNameResolverMethodDebug("ODNameResolver","GetSession");
  648.     
  649.     return _fSession;
  650. }
  651.  
  652. //------------------------------------------------------------------------------
  653. // ODNameResolver::GetPartFromToken
  654. //------------------------------------------------------------------------------
  655.  
  656. SOM_Scope ODPart*  SOMLINK ODNameResolverGetPartFromToken(ODNameResolver *somSelf, Environment *ev,
  657.         OSLToken* token)
  658. {
  659. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  660.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetPartFromToken");
  661.  
  662.     OSLContext    context;
  663.     ODPart*        part;
  664.  
  665.     if (OSErr error = OSLGetTokenContext(token, &context))
  666.     {
  667.         part = kODNULL;
  668.         ODSetSOMException(ev, error);
  669.     }
  670.     else
  671.         part = PartFromContext(&context);
  672.     
  673.     ASSERT_FRAME_MATCHES_PART( ev, FrameFromContext(&context), part );
  674.     return part;
  675. }
  676.  
  677. //------------------------------------------------------------------------------
  678. // ODNameResolver::AddNewContextPartToTopOfStack
  679. //------------------------------------------------------------------------------
  680.  
  681. SOM_Scope void  SOMLINK ODNameResolverAddNewContextPartToTopOfStack(ODNameResolver *somSelf, Environment *ev,
  682.         ODPart* contextPart)
  683. {
  684.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  685.     ODNameResolverMethodDebug("ODNameResolver","AddNewContextPartToTopOfStack");
  686.  
  687.     _fCurrentContextPart->AddFirst(contextPart);
  688. }
  689.  
  690. //------------------------------------------------------------------------------
  691. // ODNameResolver::DeleteTopOfContextPartStack
  692. //------------------------------------------------------------------------------
  693.  
  694. SOM_Scope void  SOMLINK ODNameResolverDeleteTopOfContextPartStack(ODNameResolver *somSelf, Environment *ev)
  695. {
  696.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  697.     ODNameResolverMethodDebug("ODNameResolver","DeleteTopOfContextPartStack");
  698.  
  699.     _fCurrentContextPart->RemoveFirst();
  700. }
  701.  
  702. //------------------------------------------------------------------------------
  703. // ODNameResolver::GetCurrentContextPart
  704. //------------------------------------------------------------------------------
  705.  
  706. SOM_Scope ODPart*  SOMLINK ODNameResolverGetCurrentContextPart(ODNameResolver *somSelf, Environment *ev)
  707. {
  708.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  709.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetCurrentContextPart");
  710.  
  711.     OSLContext    curContext;
  712.  
  713.     // IF WE'RE IN THE OSL, THE OSL IS DETERMINING THE CONTEXT. OTHERWISE, WE
  714.     //    KEEP THAT STATE.
  715.     if (_fCurrentlyResolving)
  716.     {
  717.         THROW_IF_ERROR(GetCurrentContext(&curContext));
  718.         return PartFromContext(&curContext);
  719.     }
  720.     else
  721. //        return _fCurrentContextPart;
  722.         return (ODPart*)_fCurrentContextPart->First();
  723. }
  724.  
  725. //------------------------------------------------------------------------------
  726. // ODNameResolver::SetCurrentContextPart
  727. //------------------------------------------------------------------------------
  728.  
  729. SOM_Scope void  SOMLINK ODNameResolverSetCurrentContextPart(ODNameResolver *somSelf, Environment *ev,
  730.         ODPart* part)
  731. {
  732.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  733.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverSetCurrentContextPart");
  734.  
  735.     // DON'T ALLOW SETTING INTERNAL OSL STATE.
  736.     ASSERTM(!_fCurrentlyResolving, kODErrUndefined, "ODNameResolver: SetCurrentContextPart: Unexpected State.");
  737.     // $$$$$ NEED TO DO REFCOUNTING HERE
  738.     _fCurrentContextPart->RemoveFirst();
  739.     _fCurrentContextPart->AddFirst(part);
  740. //    _fCurrentContextPart = part;
  741. }
  742.  
  743. //------------------------------------------------------------------------------
  744. // ODNameResolver::GetContextForPart
  745. //------------------------------------------------------------------------------
  746.  
  747. SOM_Scope void  SOMLINK ODNameResolverGetContextForPart(ODNameResolver *somSelf, Environment *ev,
  748.         ODPart* part,
  749.         ODFrame* frame,
  750.         OSLContext* context)
  751. {
  752.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  753.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetContextForPart");
  754.  
  755.     SOM_TRY
  756.  
  757.     OSLContext            localContext;
  758.     SIContextTableKey    key(part, frame);
  759.  
  760. //    if (frame)
  761.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  762.  
  763.     if (part == kODAppShell)
  764.         *context = _fRootContext;
  765.     else if (_fContextTable->GetValue(&key, context))
  766.         ;
  767.     else
  768.     {
  769.         somSelf->CreateContext(ev, part, frame, &localContext);
  770.         _fContextTable->ReplaceEntry(&key, &localContext);
  771.         *context = localContext;
  772.     }
  773.  
  774.     SOM_CATCH_ALL
  775.     SOM_ENDTRY
  776. }
  777.  
  778. //------------------------------------------------------------------------------
  779. // ODNameResolver::CreateContext
  780. //------------------------------------------------------------------------------
  781.  
  782. SOM_Scope void  SOMLINK ODNameResolverCreateContext(ODNameResolver *somSelf, Environment *ev,
  783.         ODPart* part,
  784.         ODFrame* frame,
  785.         OSLContext* context)
  786. {
  787. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  788.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverCreateContext");
  789.  
  790.     SOM_TRY
  791.  
  792.     SIContext*    siContext;
  793.  
  794.     context->getCallerProc = ReturnCallbackFuncCaller;
  795.  
  796.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  797.     siContext = new SIContext(ev, part, frame, somSelf);
  798.  
  799.     context->refCon = (long)siContext;
  800.  
  801.     SOM_CATCH_ALL
  802.     SOM_ENDTRY
  803. }
  804.  
  805. //------------------------------------------------------------------------------
  806. // ODNameResolver::FlushContextCache
  807. //------------------------------------------------------------------------------
  808.  
  809. SOM_Scope void  SOMLINK ODNameResolverFlushContextCache(ODNameResolver *somSelf, Environment *ev)
  810. {
  811.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  812.     ODNameResolverMethodDebug("ODNameResolver","FlushContextCache");
  813.  
  814.     OSLContext                value;
  815.     OpenHashTableIterator   i(_fContextTable);
  816.     
  817.     if (_fHashTableRefCount == 0)
  818.         for (i.First((void*) 0, &value); i.IsNotComplete(); i.Next((void*) 0, &value))
  819.         {
  820.             DeleteAContext(&value);
  821.             i.RemoveCurrent();
  822.         }
  823. }
  824.  
  825. //------------------------------------------------------------------------------
  826. // ODNameResolver::NeedContextCache
  827. //------------------------------------------------------------------------------
  828.  
  829. SOM_Scope void  SOMLINK ODNameResolverNeedContextCache(ODNameResolver *somSelf, Environment *ev,
  830.         ODBoolean lockIt)
  831. {
  832.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  833.     ODNameResolverMethodDebug("ODNameResolver","NeedContextCache");
  834.  
  835.     if (lockIt) {
  836.         WASSERT(_fHashTableRefCount >= 0);
  837.         ++_fHashTableRefCount;
  838.     }
  839.     else {
  840.         --_fHashTableRefCount;
  841.         WASSERT(_fHashTableRefCount >= 0);
  842.     }
  843. }
  844.  
  845. //------------------------------------------------------------------------------
  846. // ODNameResolver::TokenIsDefault
  847. //------------------------------------------------------------------------------
  848. SOM_Scope ODBoolean  SOMLINK ODNameResolverTokenIsDefault(ODNameResolver *somSelf, Environment *ev,
  849.         AEDesc* token )
  850. {
  851.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  852.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverTokenIsDefault");
  853.  
  854.     WASSERT( token->descriptorType == typeUserToken );
  855.     return SIContextFromOSLToken(somSelf, token)->IsDefaultToken();
  856. }
  857.  
  858. //------------------------------------------------------------------------------
  859. // GetUserODToken
  860. //
  861. //    Get the "user" token from the token that the OSL passes around.
  862. //
  863. //    The userToken is the first four bytes.
  864. //------------------------------------------------------------------------------
  865.  
  866. ODDesc* GetUserODToken(OSLToken* oslToken)
  867. {
  868.     return *((ODDesc**)(*(oslToken->dataHandle)));
  869. }
  870.  
  871. //------------------------------------------------------------------------------
  872. // ODNameResolver::GetUserToken
  873. //
  874. //    Optimization: Don't have make OD token into AEDesc. We know the format of
  875. //    an OSLToken exactly. The ODDesc* will be in the first four bytes of the
  876. //    data.
  877. //------------------------------------------------------------------------------
  878.  
  879. SOM_Scope ODDesc*  SOMLINK ODNameResolverGetUserToken(ODNameResolver *somSelf, Environment *ev,
  880.         ODOSLToken* token)
  881. {
  882. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  883.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetUserToken");
  884.  
  885.     ODDesc*    retVal = kODNULL;
  886.  
  887.     SOM_TRY
  888.         AEDesc    tokenAsAEDesc;
  889.  
  890.         if ( token->GetDescType(ev) != typeUserToken)
  891.             THROW( kODErrNotAnODToken );
  892.  
  893.         THROW_IF_ERROR(ODDescToAEDesc(token, &tokenAsAEDesc));
  894.         retVal = GetUserODToken(&tokenAsAEDesc);
  895.         AEDisposeDesc(&tokenAsAEDesc);
  896. #if 0
  897.         AEDesc tokenAsAEDesc;
  898.         THROW_IF_ERROR( ODDescToAEDesc( token, &tokenAsAEDesc ) );
  899.         if ( tokenAsAEDesc.descriptorType != typeUserToken)
  900. //            THROW( kODErrInvalidParameter );
  901.     
  902.         if ( tokenAsAEDesc.dataHandle == kODNULL)
  903. //            THROW( kODErrInvalidParameter );
  904.     
  905.         AEDesc* userAEDesc = new AEDesc;
  906.         // EXTRACT USER TOKEN FROM DATAHANDLE.
  907.         *userAEDesc = *((AEDesc*)(*(tokenAsAEDesc.dataHandle)));
  908.         AEDesc    tempAEDesc;
  909.         AEDuplicateDesc(userAEDesc, &tempAEDesc);
  910.     
  911.         ODDesc* userToken = new ODDesc();
  912.         THROW_IF_NULL(userToken);
  913.         userToken->InitODDesc(ev);
  914.     
  915.         THROW_IF_ERROR( AEDescToODDesc(userAEDesc, userToken ) );
  916.         userToken->SetHadToAllocate(ev);
  917.     
  918.         *desc = userToken;
  919. #endif /* 0 */
  920.     SOM_CATCH_ALL
  921.     SOM_ENDTRY
  922.     
  923.     return retVal;
  924. }
  925.  
  926. //------------------------------------------------------------------------------
  927. // ODNameResolver::IsODToken
  928. //------------------------------------------------------------------------------
  929.  
  930. SOM_Scope ODBoolean  SOMLINK ODNameResolverIsODToken(ODNameResolver *somSelf, Environment *ev,
  931.         ODOSLToken* token)
  932. {
  933. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  934.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverIsODToken");
  935.     WASSERT( token );
  936.     return token->GetDescType(ev) == typeUserToken;
  937. }
  938.  
  939. //------------------------------------------------------------------------------
  940. // ODNameResolver::GetContextFromToken
  941. //------------------------------------------------------------------------------
  942.  
  943. SOM_Scope void  SOMLINK ODNameResolverGetContextFromToken(ODNameResolver *somSelf, Environment *ev,
  944.         ODOSLToken* token,
  945.         ODPart** part,
  946.         ODFrame** frame)
  947. {
  948. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  949.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetContextFromToken");
  950.     
  951.     WASSERT(part);
  952.     WASSERT(frame);
  953.  
  954.     SOM_TRY
  955.         AEDesc realToken;
  956.         THROW_IF_ERROR( ODDescToAEDesc( token, &realToken ) );
  957.     
  958.         WASSERT( realToken.descriptorType == typeUserToken );
  959.         *part = kODNULL;
  960.         *frame = kODNULL;
  961.         
  962.         // $$$$$This is really really really gross!  Why the hell can't we define
  963.         // a struct so we don't have to blindly grop around inside the handle?
  964.         //    I agree-NP-it will be done.
  965.     
  966.         OSLContext context = *(OSLContext*)
  967.                 ((*(realToken.dataHandle))+sizeof(ODDesc*));
  968.         (void)AEDisposeDesc( &realToken );
  969.         *part = PartFromContext(&context);
  970.         *frame = FrameFromContext(&context);
  971.         ASSERT_FRAME_MATCHES_PART( ev, *frame, *part );
  972.     SOM_CATCH_ALL
  973.     SOM_ENDTRY
  974. }
  975.  
  976. //------------------------------------------------------------------------------
  977. // ODNameResolver::CreateSwapToken
  978. //------------------------------------------------------------------------------
  979.  
  980. SOM_Scope void  SOMLINK ODNameResolverCreateSwapToken(ODNameResolver *somSelf, Environment *ev,
  981.         ODOSLToken* token,
  982.         ODPart* part,
  983.         ODFrame* frame)
  984. {
  985.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  986.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverCreateSwapToken");
  987.  
  988.     SOM_TRY
  989.  
  990. //    if (frame)
  991.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  992.     
  993.     OSLToken localToken ;
  994.     THROW_IF_ERROR( ODDescToAEDesc( token, &localToken ) );
  995.  
  996.     OSLSetTokenDescType(&localToken, kSwitchDescType);
  997.  
  998.     OSLContext                context;
  999.  
  1000.     somSelf->GetContextForPart(ev, part, frame, &context);
  1001.     OSLSetTokenContext(&localToken, &context);
  1002.  
  1003.     THROW_IF_ERROR( AEDescToODDesc( &localToken, token ) );
  1004.     (void)AEDisposeDesc( &localToken );
  1005.  
  1006.     SOM_CATCH_ALL
  1007.     SOM_ENDTRY
  1008. }
  1009.  
  1010. //------------------------------------------------------------------------------
  1011. // ODNameResolver::CallObjectAccessor
  1012. //------------------------------------------------------------------------------
  1013.  
  1014. SOM_Scope void  SOMLINK ODNameResolverCallObjectAccessor(ODNameResolver *somSelf, Environment *ev,
  1015.         ODPart* part,
  1016.         ODDescType desiredClass,
  1017.         ODOSLToken* containerToken,
  1018.         ODDescType containerClass,
  1019.         ODDescType keyForm,
  1020.         ODDesc* keyData,
  1021.         ODOSLToken* token)
  1022. {
  1023.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  1024.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverCallObjectAccessor");
  1025.  
  1026.     SOM_TRY
  1027.  
  1028.     OSLContext    curContext;
  1029.  
  1030.     // CHECK THAT CURRENT CONTEXT IS THE SAME AS CONTEXT FOR thePart
  1031.     if (part != somSelf->GetCurrentContextPart(ev))
  1032.         THROW(errAEAccessorNotFound);
  1033.  
  1034.     THROW_IF_ERROR(GetCurrentContext(&curContext));
  1035.  
  1036. //    Don't bother putting anything *in* realToken since it'll just get
  1037. //    overwritten later (by NewODToken)
  1038.     AEDesc realToken = NULL_DESCRIPTOR_DEFINITION;
  1039. #define FIX_ODNAMERESOLVERCALLOBJECTACCESSOR_LEAK 0
  1040. #if FIX_ODNAMERESOLVERCALLOBJECTACCESSOR_LEAK
  1041. //    THIS IS SILLY. WE NEED TO REDESIGN NewODToken SO IT'S SMARTER ABOUT THIS.
  1042.     somSelf->DisposeToken(ev, token);
  1043.     token = new ODOSLToken();
  1044.     token->InitODOSLToken(ev);
  1045. #endif
  1046.     AEDesc realContainer;
  1047.     THROW_IF_ERROR( ODDescToAEDesc( containerToken, &realContainer ) );
  1048.  
  1049.     AEDesc realData;
  1050.     THROW_IF_ERROR( ODDescToAEDesc( keyData, &realData ) );
  1051.  
  1052.     THROW_IF_ERROR(OSLCallObjectAccessor(desiredClass,
  1053.                                         &realContainer,
  1054.                                         containerClass,
  1055.                                         keyForm,
  1056.                                         &realData,
  1057.                                         &realToken));
  1058.     (void)AEDisposeDesc( &realContainer );
  1059.     (void)AEDisposeDesc( &realData );
  1060.  
  1061.     THROW_IF_ERROR( AEDescToODDesc(&realToken, token ) );
  1062.     (void)AEDisposeDesc( &realToken );
  1063.  
  1064.     THROW_IF_ERROR(SetCurrentContext(&curContext));
  1065.  
  1066.     SOM_CATCH_ALL
  1067.     SOM_ENDTRY
  1068. }
  1069.  
  1070. //------------------------------------------------------------------------------
  1071. // ODNameResolver::DisposeToken
  1072. //------------------------------------------------------------------------------
  1073.  
  1074. SOM_Scope void  SOMLINK ODNameResolverDisposeToken(ODNameResolver *somSelf, Environment *ev,
  1075.         ODOSLToken* theToken)
  1076. {
  1077. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  1078.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverDisposeToken");
  1079.  
  1080.     SOM_TRY
  1081.         // don't assert this: it could be a list too
  1082. //        WASSERT(somSelf->IsODToken(ev, theToken));
  1083.     
  1084. #if (ODDebug && LOGGING)
  1085.         if (somSelf->IsODToken(ev, theToken)) {
  1086.             ODPart*        debugContextPart;
  1087.             ODFrame*    debugContextFrame;
  1088.             somSelf->GetContextFromToken(ev, theToken, &debugContextPart, &debugContextFrame);
  1089.             LOG("resolved context - part: %8.8x, frame: %8.8x\n", debugContextPart, debugContextFrame);
  1090.         }
  1091. #endif
  1092.         OSLToken localToken;
  1093.         THROW_IF_ERROR( ODDescToAEDesc( theToken, &localToken ) );
  1094.         // NEED TO DELETE THE OBJECT HERE BECAUSE ONLY localToken GETS PASSED
  1095.         //    BACK INTO OUR CODE FROM THE OSL.
  1096.         ODDeleteObject(theToken);
  1097.         THROW_IF_ERROR(OSLDisposeToken(&localToken));
  1098.     SOM_CATCH_ALL
  1099.     SOM_ENDTRY
  1100. }
  1101.  
  1102. //------------------------------------------------------------------------------
  1103. // ReturnCallbackFuncCaller
  1104. //------------------------------------------------------------------------------
  1105.  
  1106. CallbackCallerProc ReturnCallbackFuncCaller(OSLCallbackSelector whichCallback)
  1107. {
  1108.     CallbackCallerProc    result;
  1109.  
  1110.     switch(whichCallback)
  1111.     {
  1112.         case kObjectAccessor:
  1113.             result = (CallbackCallerProc)CallObjectAccessor;
  1114.             break;
  1115.         case kCallbackFlagsGetter:
  1116.             result = (CallbackCallerProc)GetAppDoesFlags;
  1117.             break;
  1118.         case kCountProc:
  1119.             result = (CallbackCallerProc)CallCountProc;
  1120.             break;
  1121.         case kCompareProc:
  1122.             result = (CallbackCallerProc)CallCompareProc;
  1123.             break;
  1124.         case kDisposeTokenProc:
  1125.             result = (CallbackCallerProc)CallDisposeTokenProc;
  1126.             break;
  1127.         case kGetMarkTokenProc:
  1128.             result = (CallbackCallerProc)CallGetMarkTokenProc;
  1129.             break;
  1130.         case kMarkProc:
  1131.             result = (CallbackCallerProc)CallMarkProc;
  1132.             break;
  1133.         case kAdjustMarksProc:
  1134.             result = (CallbackCallerProc)CallAdjustMarksProc;
  1135.             break;
  1136.         case kGetErrDescProc:
  1137.             result = (CallbackCallerProc)CallGetErrDescProc;
  1138.             break;
  1139.         default:
  1140.             ASSERTM(false, 0, "NamRslvr.ReturnCallbackFuncCaller: Reached default case in switch.");
  1141.             break;
  1142.     }
  1143.  
  1144.     return result;
  1145. }
  1146.  
  1147. //------------------------------------------------------------------------------
  1148. // GetSI
  1149. //
  1150. //    Given a context refCon, find the ODSemanticInterface object and the ODPart
  1151. //    object corresponding. If they can't be found, return kODFalse; return
  1152. //    kODTrue otherwise.
  1153. //------------------------------------------------------------------------------
  1154.  
  1155. static ODSemanticInterface* GetSI(long contextRefCon, ODPart** thePart)
  1156. {
  1157.     ODNameResolver*    nameResolver
  1158.             = ((SIContext*)contextRefCon)->GetNameResolver();
  1159.     
  1160.     *thePart = ((SIContext*)contextRefCon)->GetPart();
  1161.     return nameResolver->AcquireSemtIntf(somGetGlobalEnvironment(),*thePart);
  1162. }
  1163.  
  1164. //------------------------------------------------------------------------------
  1165. // CreateNewODOSLToken
  1166. //
  1167. //    This function shares a lot of code with NewODToken. Let's consolidate!
  1168. //    -NP 6/21/95
  1169. //
  1170. //    Create an "OpenDoc token", one with context information and an embedded
  1171. //    ODDesc* for a user token.
  1172. //------------------------------------------------------------------------------
  1173.  
  1174. SOM_Scope void  SOMLINK ODNameResolverCreateNewODOSLToken(ODNameResolver *somSelf, Environment *ev,
  1175.         AEDesc* odOSLToken,
  1176.         ODDesc* userToken,
  1177.         ODPart* part,
  1178.         ODFrame* frame)
  1179. {
  1180.     OSLContext    context;
  1181.  
  1182.     somSelf->GetContextForPart(ev, part, frame, &context);
  1183.     odOSLToken->descriptorType = typeUserToken;
  1184.     odOSLToken->dataHandle = (Handle)ODNewHandle(sizeof(ODDesc*)
  1185.                                 + sizeof(OSLContext));
  1186.     OSLSetTokenContext(odOSLToken, &context);
  1187.     SetUserODToken(odOSLToken, userToken);
  1188. }
  1189.  
  1190. //------------------------------------------------------------------------------
  1191. // NewODToken
  1192. //
  1193. //    Takes the already allocated newToken and openDocToken and sets up an OpenDoc
  1194. //    style token.
  1195. //    Places a null descriptor in openDocToken as the "user token"
  1196. //------------------------------------------------------------------------------
  1197.  
  1198. static void NewODToken( ODNameResolver* me, ODOSLToken* openDocToken,
  1199.                          ODPart* part, ODFrame* frame, OSLToken* newToken )
  1200. {
  1201.     Environment*    ev = somGetGlobalEnvironment();
  1202.     OSLContext        context;
  1203.  
  1204.     WASSERT(openDocToken);
  1205.  
  1206.     // CHECK TO SEE IF THIS IS A NULL TOKEN
  1207.     DescType dt = openDocToken->GetDescType(ev);
  1208. //    ODBoolean okToOverwrite = (dt == 'dead') || (dt == typeNull);
  1209.     ODBoolean okToOverwrite = (dt == typeNull);
  1210.  
  1211. //    if (dt != 'dead' && dt != typeNull && dt != typeAEList &&
  1212. //            dt != typeObjectBeingExamined)
  1213. //    This ASSERT is bogus as the token can be anyone's mark token
  1214. //    if (dt != typeNull && dt != typeAEList && dt != typeObjectBeingExamined)
  1215. //        WARN("Some unknown descriptor type in NewODToken.");
  1216.  
  1217.     // MUST SAVE OFF ORIGINAL OSLToken FOR CERTAIN TOKENS.
  1218.     AEDesc savedToken;
  1219.     if ( !okToOverwrite )
  1220.         // what's there now MATTERS; save it for wrapping
  1221.         savedToken = *newToken;
  1222.     else
  1223.         MakeNULLDesc(&savedToken);
  1224.  
  1225.     // INITIALIZE OSLToken TO THE RIGHT THING.
  1226.     newToken->descriptorType = typeUserToken;
  1227.     // $$$$$ THIS KNOWLEDGE OF HOW BIG THE STRUCTURE IS SHOULD BE ENCAPSULATED
  1228.     //    SOMEWHERE ELSE!!!!
  1229.     Handle h = (Handle)ODNewHandle(sizeof(ODDesc*) + sizeof(OSLContext));
  1230.     newToken->dataHandle = h;
  1231.     // GET AN OSLContext FOR THIS PART.
  1232.     me->GetContextForPart(ev, part, frame, &context);
  1233.     OSLSetTokenContext(newToken, &context);
  1234.  
  1235.     // CREATE USER TOKEN AND STICK IT IN THE OSLToken.
  1236.     ODDesc* tmpToken = new ODDesc();
  1237.     THROW_IF_NULL(tmpToken);
  1238.     tmpToken->InitODDesc(ev);
  1239.     THROW_IF_ERROR( AEDescToODDesc( &savedToken, tmpToken ) );
  1240.     SetUserODToken(newToken, tmpToken);
  1241.  
  1242.     // FINALLY INITIALIZE openDocToken AS WELL
  1243.     THROW_IF_ERROR( AEDescToODDesc(newToken, openDocToken ) );
  1244. }
  1245.  
  1246. //------------------------------------------------------------------------------
  1247. // CopyContextIntoToken
  1248. //
  1249. //    Move 2nd 8 bytes of dataHandle from one token to the other.
  1250. //    Should use OSLGetTokenContext and OSLSetTokenContext instead.
  1251. //------------------------------------------------------------------------------
  1252.  
  1253. static void CopyContextIntoToken(const OSLToken* sourceToken,
  1254.                                     OSLToken* destToken)
  1255. {
  1256.     OSLContext    context = GETBYTESOFHANDLE(sourceToken->dataHandle, OSLContext,
  1257.                                             sizeof(AEDesc));
  1258.  
  1259.     SETBYTESOFHANDLE(destToken->dataHandle, OSLContext, context,
  1260.                         sizeof(AEDesc));
  1261. }
  1262.  
  1263. //------------------------------------------------------------------------------
  1264. // TokenDefaultCanHandle
  1265. //------------------------------------------------------------------------------
  1266.  
  1267. static ODBoolean TokenDefaultCanHandle( Environment* ev,
  1268.         ODNameResolver* resolver, ODOSLToken* token )
  1269. {
  1270.     return true;
  1271. #if 0
  1272.     ODBoolean result = kODFalse;
  1273.     AEDesc realToken;
  1274.     THROW_IF_ERROR( ODDescToAEDesc( token, &realToken ) );
  1275.     switch ( realToken.descriptorType )
  1276.     {
  1277.         case typeUserToken:
  1278.             if ( !resolver->TokenIsDefault(ev, &realToken) )
  1279.             {
  1280.                 ODDesc* userToken;
  1281.                 userToken = resolver->GetUserToken( ev, token );
  1282.                 AEDesc realUserToken;
  1283.                 THROW_IF_ERROR( ODDescToAEDesc( userToken, &realUserToken ) );
  1284.  
  1285.                 ODBoolean isStandardToken =
  1286.                         CanBeStandardPartToken( &realUserToken )
  1287.                         || realUserToken.descriptorType == typeNull
  1288.                         || realUserToken.descriptorType == typeObjectBeingExamined;
  1289.  
  1290.                 AEDisposeDesc(&realUserToken);
  1291.  
  1292.                 result = isStandardToken;
  1293.             }
  1294.             else
  1295.                 result = kODTrue;
  1296.             break;
  1297.         case typeNull:
  1298.             result = kODTrue;
  1299.             break;
  1300.     }
  1301.     (void)AEDisposeDesc( &realToken );
  1302.     return result;
  1303. #endif
  1304. }
  1305.  
  1306. //------------------------------------------------------------------------------
  1307. // GetCallObjectAccessor
  1308. //
  1309. //    Used for compile-time type checking only.
  1310. //------------------------------------------------------------------------------
  1311.  
  1312. static ObjectAccessorCaller GetCallObjectAccessor()
  1313. {
  1314.     return CallObjectAccessor;
  1315. }
  1316.  
  1317. //------------------------------------------------------------------------------
  1318. // CallObjectAccessor
  1319. //------------------------------------------------------------------------------
  1320.  
  1321. static OSErr CallObjectAccessor(DescType        desiredClass,
  1322.                                     const OSLToken*    containerToken,
  1323.                                     DescType        containerClass,
  1324.                                     DescType        keyForm,
  1325.                                     const AEDesc*    keyData,
  1326.                                     OSLToken*        value,
  1327.                                     Boolean*        procFound,
  1328.                                     long            contextRefCon)
  1329. {
  1330.     OSErr                        error = noErr;
  1331.     TempODSemanticInterface        si = kODNULL;
  1332.     ODPart*                        thePart;
  1333.     Environment*                ev = somGetGlobalEnvironment();
  1334.     ODNameResolver*                nameResolver
  1335.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1336.     ODFrame* const                kNoFrameInfo = kODNULL;
  1337.     ODBoolean                    allocatedContainerToken = kODFalse;
  1338.     
  1339.     *procFound = false;
  1340.  
  1341.     TRY
  1342.         si = GetSI(contextRefCon, &thePart);
  1343.     
  1344.         ODDesc* dataODDesc = new ODDesc();
  1345.         THROW_IF_NULL(dataODDesc);
  1346.         dataODDesc->InitODDesc(ev);
  1347.         THROW_IF_ERROR( AEDescToODDesc( (AEDesc*)keyData, dataODDesc ));
  1348.     
  1349.         // INITIALIZE TOKENS (OPTIMIZATION?: SHOULD ONLY DO THIS IF WE CAN
  1350.         //    ACTUALLY CALL AN OBJECT ACCESSOR.)
  1351.     
  1352.         ODOSLToken* containerODDesc = new ODOSLToken();
  1353.         THROW_IF_NULL(containerODDesc);
  1354.         containerODDesc->InitODOSLToken(ev);
  1355.         THROW_IF_ERROR(AEDescToODDesc((OSLToken*)containerToken,
  1356.                                         containerODDesc));
  1357.     
  1358.         ODOSLToken* valueWrapper = new ODOSLToken();
  1359.         THROW_IF_NULL(valueWrapper);
  1360.         valueWrapper->InitODOSLToken(ev);
  1361.     
  1362.         OSLContext context;
  1363.         GetCurrentContext(&context);
  1364.         ODFrame* frame = FrameFromContext(&context);
  1365.         ASSERT_FRAME_MATCHES_PART( ev, frame, thePart );
  1366.     
  1367.         if (!nameResolver->IsODToken(ev, valueWrapper))
  1368.             NewODToken( nameResolver, valueWrapper, thePart, frame, value);
  1369.     
  1370.         //  HANDLE NULL CONTAINER TOKEN.
  1371.         if (!nameResolver->IsODToken(ev, containerODDesc))
  1372.         {
  1373.             NewODToken(nameResolver, containerODDesc, thePart,
  1374.                         frame,  (AEDesc*)containerToken);
  1375.             allocatedContainerToken = kODTrue;
  1376.         }
  1377.     
  1378.         if ( si )
  1379.         {
  1380.             TRY
  1381.                 si->CallObjectAccessor(ev, thePart, (ODDescType)desiredClass,
  1382.                                     containerODDesc,
  1383.                                     (ODDescType)containerClass,
  1384.                                     (ODDescType)keyForm, dataODDesc,
  1385.                                     valueWrapper);
  1386.                 SetIsDefaultToken(nameResolver, valueWrapper, kODFalse);
  1387.             CATCH_ALL
  1388.                 error = ErrorCode();
  1389.             ENDTRY
  1390.         }
  1391.     
  1392.         if ( (error == errAEEventNotHandled || !si)
  1393.                 && TokenDefaultCanHandle( ev, nameResolver, containerODDesc) )
  1394.         {
  1395.             ODMessageInterface* msgintf =
  1396.                     nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1397.             DefaultAccessorSI* defaultSI =
  1398.                     (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1399.             
  1400.             TRY
  1401.                 defaultSI->CallObjectAccessor(ev, thePart, desiredClass,
  1402.                         containerODDesc, containerClass, keyForm,
  1403.                         dataODDesc, valueWrapper);
  1404.                 SetIsDefaultToken(nameResolver, valueWrapper, kODTrue);
  1405.                 error = kODNoError;
  1406.             CATCH_ALL
  1407.                 error = ErrorCode();
  1408.             ENDTRY
  1409.         }
  1410.  
  1411.         // <eeh> part of memory leak fixing though I no longer remember
  1412.         // quite what leak....
  1413.  
  1414.         if ( error == noErr )
  1415.             THROW_IF_ERROR( ODDescToAEDesc(valueWrapper, value) );
  1416.  
  1417.         ODDeleteObject(valueWrapper);
  1418.         ODDeleteObject(dataODDesc);
  1419.         if (allocatedContainerToken)
  1420.         {
  1421.             ODDesc*     userToken = nameResolver->GetUserToken(ev, containerODDesc);
  1422.             DescType dt = nameResolver->GetUserToken(ev, containerODDesc)
  1423.                                             ->GetDescType(ev);
  1424.  
  1425.             // $$$$$ SHOULDN'T USE NEWODTOKEN FOR CONTAINERS. IT ALLOCATES
  1426.             //    A AEDESC WHEN WE DON'T NEED IT. HERE WE CHECK TO SEE IF IT DID
  1427.             //    THIS AND GET RID OF IT IF SO. FIX THIS!!!!!
  1428. //            if ( (dt == 'dead') || (dt == typeNull)
  1429. //                    || (dt == typeObjectBeingExamined) )
  1430.             if ( (dt == typeNull) || (dt == typeObjectBeingExamined) )
  1431.                 AEDisposeDesc((AEDesc*)containerToken);
  1432.  
  1433.             nameResolver->DisposeToken(ev, containerODDesc);
  1434.         }
  1435. #define FIX_FOR_EVERY_LEAK 1
  1436. #if FIX_FOR_EVERY_LEAK
  1437.         else
  1438.             ODDeleteObject(containerODDesc);
  1439. #endif
  1440.     CATCH_ALL
  1441.         error = ErrorCode();
  1442.     ENDTRY
  1443.  
  1444.     return error;
  1445. }
  1446.  
  1447. //------------------------------------------------------------------------------
  1448. // GetGetAppDoesFlags
  1449. //
  1450. //    Used for compile-time type checking only.
  1451. //------------------------------------------------------------------------------
  1452.  
  1453. static CallbackFlagsGetter GetGetAppDoesFlags()
  1454. {
  1455.     return GetAppDoesFlags;
  1456. }
  1457.  
  1458. //------------------------------------------------------------------------------
  1459. // GetAppDoesFlags
  1460. //------------------------------------------------------------------------------
  1461.  
  1462. static long GetAppDoesFlags(long contextRefCon)
  1463. {
  1464.     ODPart*                    thePart;
  1465.     TempODSemanticInterface    si = GetSI(contextRefCon, &thePart);
  1466.     
  1467.     if( !si )
  1468.         return kAEIDoMinimum;
  1469.     else
  1470.     {
  1471.         Environment* ev = somGetGlobalEnvironment();
  1472.         long result = si->GetOSLSupportFlags(ev);
  1473.         return result;
  1474.     }
  1475. }
  1476.  
  1477. //------------------------------------------------------------------------------
  1478. // GetSpecialProc
  1479. //
  1480. //    Lookup special proc given a context. Return kODFalse if not found, kODTrue
  1481. //    otherwise.
  1482. //------------------------------------------------------------------------------
  1483. #if 0
  1484. static ODBoolean GetSpecialProc(long                            contextRefCon,
  1485.                                     ODSemanticInterface*&        si,
  1486.                                     ODPart*&                    thePart)
  1487. {
  1488.     si = GetSI(contextRefCon, &si, &thePart);
  1489.     if( !si )
  1490.         return kODFalse;
  1491.  
  1492. //    theSI->GetSpecialHandler(funcType, &proc, &refCon);
  1493.  
  1494. //    if (!proc)
  1495. //        return kODFalse;
  1496.     
  1497.     return kODTrue;
  1498. }
  1499. #endif
  1500. //------------------------------------------------------------------------------
  1501. // CallCountProcAux
  1502. //------------------------------------------------------------------------------
  1503.  
  1504. static void CallCountProcAux(DescType            desiredClass,
  1505.                                 DescType        containerClass,
  1506.                                 const OSLToken*    container,
  1507.                                 long*            result,
  1508.                                 long            contextRefCon,
  1509.                                 ODOSLToken*        containerWrapper)
  1510. {
  1511.     ODPart*                        thePart;
  1512.     Environment*                ev = somGetGlobalEnvironment();
  1513.     OSErr                        error = noErr;
  1514.     ODOSLToken*                    newContainerWrapper = kODNULL;
  1515.     ODNameResolver*                nameResolver
  1516.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1517.  
  1518.     {
  1519.         TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  1520.     
  1521.         // TRY WITH THE PART'S SI FIRST
  1522.         if (si)
  1523.         {
  1524.             TRY
  1525.                 si->CallCountProc(ev, thePart, desiredClass, containerClass,
  1526.                                         containerWrapper, (ODSLong*)result);
  1527.             CATCH_ALL
  1528.                 error = ErrorCode();
  1529.             ENDTRY
  1530.         } else
  1531.             error = errAEEventNotHandled;
  1532.     }
  1533.  
  1534.     // SOME ERROR OCCURRED. TRY DEFAULT SI
  1535.     if (error == errAEEventNotHandled
  1536.             && TokenDefaultCanHandle( ev, nameResolver, containerWrapper))
  1537.     {
  1538.         TRY
  1539.             ODMessageInterface* msgintf =
  1540.                     nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1541.             DefaultAccessorSI* defaultSI =
  1542.                     (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1543.     
  1544.             defaultSI->CallCountProc(ev, thePart, desiredClass,
  1545.                                         containerClass, containerWrapper,
  1546.                                         (ODSLong*)result);
  1547.             error = noErr;
  1548.         CATCH_ALL
  1549.             error = ErrorCode();
  1550.         ENDTRY
  1551.         
  1552.         THROW_IF_ERROR( error );
  1553.     }
  1554. }
  1555.  
  1556. //------------------------------------------------------------------------------
  1557. // GetCallCountProc
  1558. //
  1559. //    Used for compile-time type checking only.
  1560. //------------------------------------------------------------------------------
  1561.  
  1562. static CountProcCaller GetCallCountProc()
  1563. {
  1564.     return CallCountProc;
  1565. }
  1566.  
  1567. //------------------------------------------------------------------------------
  1568. // CallCountProc
  1569. //------------------------------------------------------------------------------
  1570.  
  1571. static OSErr CallCountProc(DescType            desiredClass,
  1572.                                 DescType        containerClass,
  1573.                                 const OSLToken*    container,
  1574.                                 long*            result,
  1575.                                 long            contextRefCon)
  1576. {
  1577.     Environment*                ev = somGetGlobalEnvironment();
  1578.     OSErr                        error = noErr;
  1579.     ODOSLToken*                    newContainerWrapper = kODNULL;
  1580.     ODDesc*                        userToken = kODNULL;
  1581.     AEDesc                        userTokenAsAEDesc;
  1582.     OSLContext                    savedCurContext;
  1583.     OSLContext                    newContext;
  1584.     ODFrame*                    theFrame;
  1585.     ODNameResolver*                nameResolver
  1586.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1587.     ODBoolean                    allocatedContainerToken = kODFalse;
  1588.  
  1589.     TRY
  1590.         // SET UP ODDESC FOR CONTAINER
  1591.         ODOSLToken* containerWrapper = new ODOSLToken();
  1592.         THROW_IF_NULL(containerWrapper);
  1593.         containerWrapper->InitODOSLToken(ev);
  1594.         THROW_IF_ERROR(AEDescToODDesc((AEDesc*)container, containerWrapper));
  1595.  
  1596.         // INITIALIZE CONTAINER TOKEN TO OPENDOC TOKEN
  1597.         //    GET USER TOKEN SO THAT WE CAN LOOK AT IT
  1598.         //    WE ASSUME HERE THAT ONLY TIME THIS CAN HAPPEN IN WHEN THE SHELL IS
  1599.         //    INVOLVED.
  1600.         if (!nameResolver->IsODToken(ev, containerWrapper))
  1601.         {
  1602.             NewODToken(nameResolver, containerWrapper, kODAppShell, kODNULL,
  1603.                         (OSLToken*)container);
  1604.             allocatedContainerToken = kODTrue;
  1605.             MakeNULLToken(&userTokenAsAEDesc); // container?
  1606.         }
  1607.         else
  1608.         {
  1609.             userToken = nameResolver->GetUserToken(ev, containerWrapper);
  1610.             THROW_IF_ERROR(ODDescToAEDesc(userToken, &userTokenAsAEDesc));
  1611.         }
  1612.  
  1613.         TRY
  1614.             CallCountProcAux(desiredClass, containerClass, container, result,
  1615.                                 contextRefCon, containerWrapper);
  1616.         CATCH_ALL
  1617.             error = ErrorCode();
  1618.         ENDTRY
  1619.  
  1620.         // TRY SWAPPING TO EMBEDDED FRAME IF THE PART RETURNS THE SPECIAL
  1621.         //    "SWAP" RESULT.
  1622.  
  1623.         // NORMALLY, WE SHOULD ONLY ALLOW SWAPPING IF THE CONTAINER IS A
  1624.         //    STANDARD PART TOKEN. HOWEVER, WHEN thePart IS kODNULL, THEN WE
  1625.         //    KNOW THAT THE APPLICATION IS THE CONTAINER AND THE REQUEST TO
  1626.         //    SWAP SHOULD BE TRANSLATED INTO A SWAP TO THE ROOT PART.
  1627.         
  1628.         // IS THERE ANOTHER CASE WE HAVE TO WORRY ABOUT?
  1629.         
  1630.         if (*result == kODCountProcSwapValue && error == noErr)
  1631.         {
  1632.             ODPart* thePart = kODNULL;
  1633.             if ( CanBeStandardPartToken( &userTokenAsAEDesc ) )
  1634.             {
  1635.                 PartFrameFromStandardPartToken( &userTokenAsAEDesc, &thePart,
  1636.                         &theFrame );
  1637.                 thePart->Acquire(ev);
  1638.             }
  1639.             else
  1640.             {
  1641.                 theFrame = GetDefaultRootFrame(ev,
  1642.                                             nameResolver->GetSession(ev));
  1643.                 thePart = theFrame->AcquirePart(ev);
  1644.             }
  1645.             
  1646.             { TempODPart tempPart = thePart; // ensure it's released
  1647.  
  1648.               THROW_IF_ERROR(GetCurrentContext(&savedCurContext));
  1649.             
  1650.               nameResolver->GetContextForPart(ev, thePart, theFrame,
  1651.                                             &newContext);
  1652.             }
  1653.             
  1654.             THROW_IF_ERROR(SetCurrentContext(&newContext));
  1655.             
  1656.             TRY
  1657.                 // SET UP A NULL CONTAINER.
  1658.  
  1659.                 // SET THE USER TOKEN TO NULL AND SET THE CONTEXT OF THE
  1660.                 //    TOKEN TO THE RIGHT THING.
  1661.  
  1662.                 ODDesc*    tempODDesc = new ODDesc();
  1663.                 THROW_IF_NULL(tempODDesc);
  1664.                 tempODDesc->InitODDesc(ev);
  1665.  
  1666. #define FIX_FOR_WHOSE_LEAK 1
  1667. #if FIX_FOR_WHOSE_LEAK
  1668.                 // SAVE OLD CONTAINER ODOSLTOKEN
  1669.                 ODOSLToken*    oldContainerWrapper = containerWrapper;
  1670.  
  1671.                 containerWrapper = new ODOSLToken();
  1672.                 THROW_IF_NULL(containerWrapper);
  1673.                 containerWrapper->InitODOSLToken(ev);
  1674. #endif
  1675.  
  1676.                 SetUserODToken((OSLToken*)container, tempODDesc);
  1677.                 OSLSetTokenContext((OSLToken*)container, &newContext);
  1678.                 THROW_IF_ERROR( AEDescToODDesc( (AEDesc*)container, containerWrapper ) );
  1679.  
  1680.                 // RESET CONTAINER CLASS
  1681.                 containerClass = typeNull;
  1682.  
  1683.                 TRY
  1684.                     CallCountProcAux(desiredClass, containerClass, container,
  1685.                                     result, newContext.refCon,
  1686.                                     containerWrapper);
  1687.                 CATCH_ALL
  1688.                     error = ErrorCode();
  1689.                 ENDTRY
  1690.                 // RESTORE PREVIOUS USER TOKEN.  Restore even in case
  1691.                 // of error so dispose will Release Frame and Part (for
  1692.                 // the common case where we tried swapping to a StdPartToken.
  1693.                 
  1694. #if FIX_FOR_WHOSE_LEAK
  1695.                 nameResolver->DisposeToken(ev, containerWrapper);
  1696.                 containerWrapper = oldContainerWrapper;
  1697. #endif
  1698.                 
  1699.                 SetUserODToken((OSLToken*)container, userToken);
  1700.                 THROW_IF_ERROR(error);
  1701.                 if ( *result == kODCountProcSwapValue )
  1702.                     THROW( errAEEventNotHandled );
  1703.             CATCH_ALL
  1704.                 THROW_IF_ERROR(SetCurrentContext(&savedCurContext));
  1705.                 RERAISE;
  1706.             ENDTRY
  1707.             
  1708.             THROW_IF_ERROR(SetCurrentContext(&savedCurContext));
  1709.         }
  1710.  
  1711.         if (allocatedContainerToken)
  1712.             nameResolver->DisposeToken(ev, containerWrapper);
  1713.     CATCH_ALL
  1714.         error = ErrorCode();
  1715.     ENDTRY
  1716.  
  1717.     (void)AEDisposeDesc( &userTokenAsAEDesc );
  1718.     return error;
  1719. }
  1720.  
  1721. //------------------------------------------------------------------------------
  1722. // GetCallCompareProc
  1723. //
  1724. //    Used for compile-time type checking only.
  1725. //------------------------------------------------------------------------------
  1726.  
  1727. static CompareProcCaller GetCallCompareProc()
  1728. {
  1729.     return CallCompareProc;
  1730. }
  1731.  
  1732. //------------------------------------------------------------------------------
  1733. // CallCompareProc
  1734. //------------------------------------------------------------------------------
  1735.  
  1736. static ODOSLToken* MakeODOSLToken( Environment* ev, ODNameResolver* nameResolver,
  1737.         ODPart* part, ODFrame* frame, const AEDesc* desc );
  1738. static ODOSLToken* MakeODOSLToken( Environment* ev, ODNameResolver* nameResolver,
  1739.         ODPart* part, ODFrame* frame, const AEDesc* desc )
  1740. {
  1741.     ODOSLToken* result = new ODOSLToken();
  1742.     THROW_IF_NULL(result);
  1743.     result->InitODOSLToken(ev);
  1744.  
  1745.     if ( noErr == AEDescToODDesc( (OSLToken*)desc, result ) )
  1746.     {
  1747.         return result;
  1748.     }
  1749.     else
  1750.     {
  1751.         ODDeleteObject(result);
  1752.         return kODNULL;
  1753.     }
  1754. }
  1755.  
  1756. static OSErr CallCompareProc(DescType            oper,
  1757.                                 const OSLToken*    obj1,
  1758.                                 const OSLToken*    obj2,
  1759.                                 ODBoolean*        result,
  1760.                                 long            contextRefCon)
  1761. {
  1762.     OSErr                        error = noErr;
  1763.     TempODSemanticInterface        si = kODNULL;
  1764.     Environment*                ev = somGetGlobalEnvironment();
  1765.     ODPart*                        thePart;
  1766.     ODOSLToken* tokenWrapper1 = kODNULL;    ODVolatile(tokenWrapper1);
  1767.     ODOSLToken* tokenWrapper2 = kODNULL;    ODVolatile(tokenWrapper2);
  1768.     ODNameResolver*                nameResolver
  1769.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1770.  
  1771.     TRY
  1772.         si = GetSI( contextRefCon, &thePart );
  1773.         ODFrame* frame = ((SIContext*)contextRefCon)->GetFrame();
  1774.         tokenWrapper1 = MakeODOSLToken( ev, nameResolver, thePart, frame, obj1 );
  1775.         tokenWrapper2 = MakeODOSLToken( ev, nameResolver, thePart, frame, obj2 );
  1776.     CATCH_ALL
  1777.         error = ErrorCode();
  1778.     ENDTRY
  1779.  
  1780.     if ( !error )
  1781.     {
  1782.         if ( si )
  1783.         {
  1784.             TRY
  1785.                 si->CallCompareProc( ev, thePart, oper, tokenWrapper1,
  1786.                                         tokenWrapper2, result );
  1787.             CATCH_ALL
  1788.                 error = ErrorCode();
  1789.             ENDTRY
  1790.         }
  1791.         
  1792.         // don't touch the error code already returned.  Return it if the
  1793.         // defaults fail.
  1794.         if ( !si || error == errAEEventNotHandled )
  1795.                     // <eeh> what value means failed to compare?
  1796.         {
  1797.             TRY
  1798.                 ODMessageInterface* msgintf =
  1799.                         nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1800.                 DefaultAccessorSI* defaultSI =
  1801.                         (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1802.                 defaultSI->CallCompareProc( ev, thePart, oper, tokenWrapper1,
  1803.                                         tokenWrapper2, result );
  1804.                 // If we got here, there was no error.
  1805.                 error = noErr;
  1806.             CATCH_ALL
  1807.                 error = ErrorCode();
  1808.             ENDTRY
  1809.         }
  1810.     }
  1811.  
  1812.     ODDeleteObject(tokenWrapper1);
  1813.     ODDeleteObject(tokenWrapper2);
  1814.     return error;
  1815. }
  1816.  
  1817. //------------------------------------------------------------------------------
  1818. // GetCallDisposeTokenProc
  1819. //
  1820. //    Used for compile-time type checking only.
  1821. //------------------------------------------------------------------------------
  1822.  
  1823. static DisposeTokenProcCaller GetCallDisposeTokenProc()
  1824. {
  1825.     return CallDisposeTokenProc;
  1826. }
  1827.  
  1828. //------------------------------------------------------------------------------
  1829. // CallDisposeTokenProc
  1830. //------------------------------------------------------------------------------
  1831.  
  1832. static OSErr CallDisposeTokenProc(OSLToken*    unneededToken,
  1833.                                     long        contextRefCon)
  1834. {
  1835.     TempODSemanticInterface        si = kODNULL;
  1836.     ODPart*                        thePart;
  1837.     Environment*                ev = somGetGlobalEnvironment();
  1838.     OSErr                        error = noErr;
  1839.     ODNameResolver*                nameResolver
  1840.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1841.     ODOSLToken*                    tokenWrapper = kODNULL;        ODVolatile(tokenWrapper);
  1842.  
  1843.     TRY
  1844.         TRY
  1845.             si = GetSI( contextRefCon, &thePart );
  1846.             tokenWrapper = new ODOSLToken();
  1847.             THROW_IF_NULL(tokenWrapper);
  1848.             tokenWrapper->InitODOSLToken(ev);
  1849.             THROW_IF_ERROR( AEDescToODDesc( unneededToken, tokenWrapper ) );
  1850.         CATCH_ALL
  1851.             error = ErrorCode();
  1852.         ENDTRY
  1853.     
  1854.         if ( !error )
  1855.         {
  1856.             ODDesc*    userToken = kODNULL;
  1857.  
  1858.             // GET A REFERENCE TO THE USER TOKEN (IF ANY) HERE, SO THAT WE STILL
  1859.             //    HAVE A VALID REFERENCE TO IT IF THE USER'S DISPOSETOKEN PROC
  1860.             //    DEALLOCATES THE ODOSLToken.
  1861.             if (nameResolver->IsODToken(ev, tokenWrapper)
  1862.                     || (unneededToken->descriptorType == kSwitchDescType))
  1863.                 userToken = GetUserODToken(unneededToken);
  1864.  
  1865.             TRY
  1866.                 if ( si )
  1867.                     si->CallDisposeTokenProc(ev, thePart, tokenWrapper);
  1868.             CATCH_ALL
  1869.                 error = ErrorCode();
  1870.             ENDTRY
  1871.         
  1872.             if ( !si || (error == errAEEventNotHandled) )
  1873.             {
  1874.                 TRY
  1875.                     ODMessageInterface* msgintf =
  1876.                             nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1877.                     DefaultAccessorSI* defaultSI =
  1878.                             (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1879.                     defaultSI->CallDisposeTokenProc(ev, thePart, tokenWrapper);
  1880.                 CATCH_ALL
  1881.                     error = ErrorCode();
  1882.                 ENDTRY
  1883.             }
  1884.     
  1885.             // ALWAYS DELETE THE USER TOKEN
  1886.             if (userToken)
  1887.                 delete userToken;
  1888.             
  1889.             // ONLY DELETE THE TOKEN ITSELF IF NO ONE ELSE HANDLED IT.
  1890.             if (error)
  1891.             {
  1892.     //            WARN("No dispose token proc handled it. NameResolver handling.");
  1893.                 ODDeleteObject(tokenWrapper);
  1894.             }
  1895.         }
  1896.     CATCH_ALL
  1897.         error = ErrorCode();
  1898.     ENDTRY
  1899.  
  1900.     // IF THERE WAS NO ERROR, MAKE SURE WE DISPOSE THE AEDESC, BUT THE OSL
  1901.     //    WON'T. IT WILL IF WE RETURN AN ERROR.
  1902.     if (error == kODNoError)
  1903.         AEDisposeDesc(unneededToken);
  1904.  
  1905.     return error;
  1906. }
  1907.  
  1908. //------------------------------------------------------------------------------
  1909. // GetMarkProc
  1910. //
  1911. //    Used for compile-time type checking only.
  1912. //------------------------------------------------------------------------------
  1913.  
  1914. static MarkProcCaller GetMarkProc()
  1915. {
  1916.     return CallMarkProc;
  1917. }
  1918.  
  1919. //------------------------------------------------------------------------------
  1920. // CallMarkProc
  1921. //------------------------------------------------------------------------------
  1922.  
  1923. static OSErr CallMarkProc(const OSLToken*    dToken,
  1924.                             const OSLToken*    markToken,
  1925.                             long            index,
  1926.                             long            contextRefCon)
  1927. {
  1928.     OSErr                        error = noErr;
  1929.     Environment*                ev = somGetGlobalEnvironment();
  1930.     ODPart*                        thePart;
  1931.     ODNameResolver*                nameResolver
  1932.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1933.  
  1934.     TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  1935.     if( !si )
  1936.         return errAENotASpecialFunction;
  1937.  
  1938.     ODOSLToken* tokenWrapper = kODNULL;            ODVolatile(tokenWrapper);
  1939.     ODOSLToken* markTokenWrapper = kODNULL;        ODVolatile(markTokenWrapper);
  1940.     TRY
  1941.         tokenWrapper = new ODOSLToken();
  1942.         THROW_IF_NULL(tokenWrapper);
  1943.         tokenWrapper->InitODOSLToken(ev);
  1944.         THROW_IF_ERROR( AEDescToODDesc( (OSLToken*)dToken, tokenWrapper ) );
  1945.  
  1946.         markTokenWrapper = new ODOSLToken();
  1947.         THROW_IF_NULL(markTokenWrapper);
  1948.         markTokenWrapper->InitODOSLToken(ev);
  1949.         THROW_IF_ERROR(AEDescToODDesc( (OSLToken*)markToken, markTokenWrapper));
  1950.         si->CallMarkProc(ev, thePart, tokenWrapper,
  1951.                                 markTokenWrapper, index);
  1952.     CATCH_ALL
  1953.         error = ErrorCode();
  1954.     ENDTRY
  1955.     
  1956.     ODDeleteObject(tokenWrapper);
  1957.     ODDeleteObject(markTokenWrapper);
  1958.     return error;
  1959. }
  1960.  
  1961. //------------------------------------------------------------------------------
  1962. // GetMarkTokenProc
  1963. //
  1964. //    Used for compile-time type checking only.
  1965. //------------------------------------------------------------------------------
  1966.  
  1967. static GetMarkTokenProcCaller GetMarkTokenProc()
  1968. {
  1969.     return CallGetMarkTokenProc;
  1970. }
  1971.  
  1972. //------------------------------------------------------------------------------
  1973. // CallGetMarkTokenProc
  1974. //------------------------------------------------------------------------------
  1975.  
  1976. static OSErr CallGetMarkTokenProc(const OSLToken*    dContainerToken,
  1977.                                     DescType        containerClass,
  1978.                                     OSLToken*        result,
  1979.                                     long            contextRefCon)
  1980. {
  1981.     OSErr                    error = noErr;
  1982.     Environment*                ev = somGetGlobalEnvironment();
  1983.     ODPart*                thePart;
  1984.     ODNameResolver*                nameResolver
  1985.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1986.  
  1987.     TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  1988.     if( !si )
  1989.         return errAENotASpecialFunction;
  1990.  
  1991.     ODOSLToken* tokenWrapper = kODNULL;        ODVolatile(tokenWrapper);
  1992.     TRY
  1993.         tokenWrapper = new ODOSLToken();
  1994.         THROW_IF_NULL(tokenWrapper);
  1995.         tokenWrapper->InitODOSLToken(ev);
  1996.         THROW_IF_ERROR( AEDescToODDesc( (OSLToken*)dContainerToken, tokenWrapper ) );
  1997.  
  1998.         ODOSLToken* resultWrapper = new ODOSLToken();
  1999.         THROW_IF_NULL(resultWrapper);
  2000.         resultWrapper->InitODOSLToken(ev);
  2001.         si->CallGetMarkTokenProc(ev, thePart, tokenWrapper,
  2002.                                                 containerClass,
  2003.                                                 resultWrapper);
  2004.         THROW_IF_ERROR( ODDescToAEDesc(resultWrapper, result));
  2005.         ODDeleteObject(resultWrapper);
  2006.     CATCH_ALL
  2007.         error = ErrorCode();
  2008.     ENDTRY
  2009.     
  2010.     ODDeleteObject(tokenWrapper);
  2011.     return error;
  2012. }
  2013.  
  2014. //------------------------------------------------------------------------------
  2015. // GetAdjustMarksProc
  2016. //
  2017. //    Used for compile-time type checking only.
  2018. //------------------------------------------------------------------------------
  2019.  
  2020. static AdjustMarksProcCaller GetAdjustMarksProc()
  2021. {
  2022.     return CallAdjustMarksProc;
  2023. }
  2024.  
  2025. //------------------------------------------------------------------------------
  2026. // CallAdjustMarksProc
  2027. //------------------------------------------------------------------------------
  2028.  
  2029. static OSErr CallAdjustMarksProc(long                newStart,
  2030.                                     long            newStop,
  2031.                                     const OSLToken*    markToken,
  2032.                                     long            contextRefCon)
  2033. {
  2034.     OSErr                    error = noErr;
  2035.     Environment*                ev = somGetGlobalEnvironment();
  2036.     ODPart*                thePart;
  2037.  
  2038.     TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  2039.     if (!si)
  2040.         return errAENotASpecialFunction;
  2041.  
  2042.     ODOSLToken* tokenWrapper = kODNULL;        ODVolatile(tokenWrapper);
  2043.     TRY
  2044.         tokenWrapper = new ODOSLToken();
  2045.         THROW_IF_NULL(tokenWrapper);
  2046.         tokenWrapper->InitODOSLToken(ev);
  2047.         THROW_IF_ERROR( AEDescToODDesc( (OSLToken*)markToken, tokenWrapper ) );
  2048.  
  2049.         si->CallAdjustMarksProc(ev, thePart, newStart, newStop,
  2050.                                                     tokenWrapper);
  2051.     CATCH_ALL
  2052.         error = ErrorCode();
  2053.     ENDTRY
  2054.     
  2055.     ODDeleteObject(tokenWrapper);
  2056.     return error;
  2057. }
  2058.  
  2059. //------------------------------------------------------------------------------
  2060. // GetGetErrDescProc
  2061. //
  2062. //    Used for compile-time type checking only.
  2063. //------------------------------------------------------------------------------
  2064.  
  2065. static GetErrDescProcCaller GetGetErrDescProc()
  2066. {
  2067.     return CallGetErrDescProc;
  2068. }
  2069.  
  2070. //------------------------------------------------------------------------------
  2071. // CallGetErrDescProc
  2072. //------------------------------------------------------------------------------
  2073.  
  2074. static OSErr CallGetErrDescProc(AEDesc**    appDescPtr,
  2075.                                     long    contextRefCon)
  2076. {
  2077.     TempODSemanticInterface        si = kODNULL;
  2078.     ODPart*                        thePart;
  2079.     Environment*                ev = somGetGlobalEnvironment();
  2080.     OSErr                        error = noErr;
  2081.     ODNameResolver*                nameResolver
  2082.         = ((SIContext*)contextRefCon)->GetNameResolver();
  2083.  
  2084.     si = GetSI(contextRefCon, &thePart);
  2085.     if (!si)
  2086.         return errAENotASpecialFunction;
  2087.  
  2088.     TRY
  2089.         ODDesc*    errorODDesc;
  2090.         si->CallGetErrDescProc(ev, thePart, &errorODDesc);
  2091.         *appDescPtr = nameResolver->AddErrDescToList(ev, errorODDesc);
  2092.     CATCH_ALL
  2093.         error = ErrorCode();
  2094.     ENDTRY
  2095.     return error;
  2096. }
  2097.  
  2098.